/*
 * Copyright 2011 Clean GWT
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cleangwt.user.client;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.LinkElement;
import com.google.gwt.dom.client.MetaElement;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.ScriptElement;

/**
 * The convienent class for managing &lt;head&gt; elements.
 * 
 * @author Jess
 * @version 1.0
 * @since 1.0
 */
public class HeadInjector {

  /**
   * Gets the document header.
   * 
   * @return the document header
   */
  private static Element getHead() {
    assert Document.get().getElementsByTagName("head").getLength() > 0;;
    Element element = Document.get().getElementsByTagName("head").getItem(0);
    return element;
  }

  /**
   * Injects javascript into the head element.
   * 
   * @param src the source
   */
  public static void injectJs(String src) {
    Element head = getHead();
    NodeList<Element> scripts = head.getElementsByTagName(ScriptElement.TAG);
    for (int i = 0; i < scripts.getLength(); i++) {
      if (src.equals(scripts.getItem(i).getAttribute("src"))) {
        return;
      }
    }
    ScriptElement script = Document.get().createScriptElement();
    script.setType("text/javascript");
    script.setSrc(src);
    head.appendChild(script);
  }

  /**
   * Injects meta info of 'http-eqiv' into the head element.
   * 
   * @param httpEqiv the http eqiv type
   * @param content the content
   */
  public static void injectMetaHttpEqiv(String httpEqiv, String content) {
    injectMeta("http-eqiv", httpEqiv, content);
  }

  /**
   * Injects meta info of 'name' into the head element.
   * 
   * @param name the name
   * @param content the content
   */
  public static void injectMeta(String name, String content) {
    injectMeta("name", name, content);
  }

  /**
   * Injects meta info into the head element.
   * 
   * @param attriuteName the attribute name
   * @param attributeValue the attriute value
   * @param content the content
   */
  private static void injectMeta(String attriuteName, String attributeValue, String content) {
    Element head = getHead();
    NodeList<Element> scripts = head.getElementsByTagName(MetaElement.TAG);
    MetaElement script = null;
    for (int i = 0; i < scripts.getLength(); i++) {
      if (attributeValue.equals(scripts.getItem(i).getAttribute(attriuteName))) {
        script = scripts.getItem(i).cast();
      }
    }
    if (script == null) {
      script = Document.get().createMetaElement();
    }
    script.setAttribute(attriuteName, attributeValue);
    script.setContent(content);
    head.appendChild(script);
  }

  /**
   * Injects javascript into the head element.
   * 
   * @param src the source
   */
  public static void injectStyleSheet(String src) {
    injectStyleSheet(src, null);
  }

  /**
   * Injects javascript into the head element.
   * 
   * @param src the source
   * @param srcToReplace the source to replace
   */
  public static void injectStyleSheet(String src, String srcToReplace) {
    Element head = getHead();
    NodeList<Element> links = head.getElementsByTagName(LinkElement.TAG);
    if (srcToReplace != null) {
      for (int i = 0; i < links.getLength(); i++) {
        if (srcToReplace.equals(links.getItem(i).getAttribute("href"))) {
          links.getItem(i).setAttribute("href", src);
          return;
        }
      }
    }
    for (int i = 0; i < links.getLength(); i++) {
      if (src.equals(links.getItem(i).getAttribute("href"))) {
        return;
      }
    }
    LinkElement link = Document.get().createLinkElement();
    link.setRel("stylesheet");
    link.setHref(src);
    head.appendChild(link);
  }

}
